package auth_https

import (
	"encoding/pem"
	"fmt"
	"github.com/yeka/zip"
	"log"
	"os"
	"path"
	"strings"
)

func SaveCertToZip(zipPath, pwd string, crtBytes, keyPriv []byte) error {

	fzip, err := os.Create(zipPath)
	if err != nil {
		return err
	}
	zipw := zip.NewWriter(fzip)
	defer func(zip *zip.Writer) {
		err := zip.Close()
		if err != nil {
			log.Println(err.Error())
		}
	}(zipw)

	fileNameAll := path.Base(zipPath)
	fileSuffix := path.Ext(zipPath)
	prefix := strings.TrimSuffix(fileNameAll, fileSuffix)

	w1, err := zipw.Encrypt(prefix+".crt", pwd, zip.AES256Encryption)
	if err != nil {
		return err
	}
	err = pem.Encode(w1, &pem.Block{Type: "CERTIFICATE", Bytes: crtBytes})
	if err != nil {
		return err
	}

	w2, err := zipw.Encrypt(prefix+".key", pwd, zip.AES256Encryption)
	if err != nil {
		return err
	}
	err = pem.Encode(w2, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyPriv})
	if err != nil {
		return err
	}

	err = zipw.Flush()
	if err != nil {
		return err
	}
	return nil
}

func OpenZip(caZip, pwd string) ([]byte, []byte, error) {
	var err error

	f, err := zip.OpenReader(caZip)
	if err != nil {
		log.Fatal(err)
	}
	defer func(f *zip.ReadCloser) {
		err := f.Close()
		if err != nil {
			log.Println("zip  Close err:", err.Error())
		}
	}(f)

	caBytes := make([]byte, 1024)
	privBytes := make([]byte, 1024)
	var n1, n2 int

	for _, file := range f.File {
		if file.IsEncrypted() {
			file.SetPassword(pwd)
		}

		fmt.Printf("打开文件: %s\n", file.Name)

		err := func(file *zip.File) error {
			// 打开 ZIP 文件中的文件
			rc, err := file.Open()
			if err != nil {
				log.Fatal(err)
			}
			defer func() {
				err := rc.Close()
				if err != nil {
					log.Println("Close", file.Name)
					return
				}
			}()

			switch path.Ext(file.Name) {
			case ".crt":
				n1, err = rc.Read(caBytes)
				if err != nil && err.Error() != "EOF" {
					fmt.Println(string(caBytes[n1]))
					return fmt.Errorf("读取 ca.crt err:%v", err.Error())
				}
				fmt.Printf("文件 %s 已写入\n", file.Name)
			case ".key":
				n2, err = rc.Read(privBytes)
				if err != nil && err.Error() != "EOF" {
					return fmt.Errorf("读取 .key err:%v", err.Error())
				}
				fmt.Printf("文件 %s 已写入\n", file.Name)
			default:
				return fmt.Errorf("文件 %s 后缀不匹配写入失败\n", file.Name)
			}
			return nil
		}(file)
		if err != nil {
			return nil, nil, err
		}
	}
	return caBytes[:n1], privBytes[:n2], nil
}
